package org.sgx.htmlminimizator.client;

import org.sgx.gwteditors.client.util.Util;

import com.google.gwt.user.client.Window;
import com.google.gwt.xml.client.*;

/**
 * 
 * @author sg
 *
 */
public class HTMLMinimizatorUtil {

public void minimize(Config c, Document doc, StringBuffer out) {
	minimize(c, doc.getDocumentElement(), out); 
}

/**
 * minimize the given htmlcode according to given configuration c. stores the output in out variable.
 * @param c
 * @param htmlCode
 * @param out
 */
public  void minimize(Config c, String htmlCode, StringBuffer out) {
	htmlCode = "<b HTMLMinimizatorUtilAttr1=\"1\">"+htmlCode+"</b>"; 
//	Window.alert(htmlCode); 
    Document doc = XMLParser.parse(htmlCode);    
	minimize(c, doc, out); 	
}



public void minimize(Config c, Node node, StringBuffer out) {
	if(c.getExtractText()) {
		if(node.getNodeType()==Node.TEXT_NODE) {
			out.append(" "+node.getNodeValue()); 
		}
	}
	else {
		if(node.getNodeType()==Node.TEXT_NODE) {
			Text t = (Text)node; 
			if(c.getPreserveSpaces() || !((Text)node).getData().trim().equals(""))
				out.append(((Text)node).getData()); 
		}
		else if(node.getNodeType()==Node.ATTRIBUTE_NODE) {
			Attr attrNode = (Attr)node; 
			String ra = c.getRemoveAttributes();
			ra = ra==null ? "" : ra; 
			boolean printAttr = false;
			if(attrNode.getName().equals("HTMLMinimizatorUtilAttr1")) {
				printAttr=false; 
			}
			else if(ra.equals("")) {
				printAttr=true; 
			}
			else {
				if(!ra.equals("*")) {
					String[] ras = ra.split(",");
					if(!Util.contains(ras, attrNode.getName())) {
						printAttr=true;						 
					}
				}
			}
			if(printAttr) {
				out.append(" "+attrNode.getName()+"=\""+attrNode.getNodeValue()+"\"");
			}
		}
		else if(node.getNodeType()==Node.ELEMENT_NODE) {
			Element elNode = (Element)node; 
			boolean extractEl = true; 
			if(node.getAttributes().getNamedItem("HTMLMinimizatorUtilAttr1")==null && 
					c.getRemoveElementWithoutText() && !elementContainText(elNode)) {
				extractEl=false; 
			}
			if(extractEl) {
				out.append("<"+elNode.getTagName()); 
				NodeList childs = elNode.getChildNodes();
				//recurse on attributes
				for (int i = 0; i < childs.getLength(); i++) {
					Node child = childs.item(i); 
					if(child.getNodeType()==Node.ATTRIBUTE_NODE)
						minimize(c, child, out); 
				}
				out.append(">"); 				
				//recurse on childs - text or other elements...
				for (int i = 0; i < childs.getLength(); i++) {
					Node child = childs.item(i); 
					if(child.getNodeType()!=Node.ATTRIBUTE_NODE)
						minimize(c, child, out); 
				}
				out.append("</"+elNode.getTagName()+">"); 
			}
		}
	}
}

private boolean elementContainText(Element el) {
	boolean foundText=false; 
	NodeList childs = el.getChildNodes();
	for (int i = 0; i < childs.getLength(); i++) {
		if(childs.item(i).getNodeType()==Node.TEXT_NODE) {
			String data = ((Text)childs.item(i)).getData(); 
			if(data!=null&& !data.trim().equals("")) {
				foundText = true; 
				break; 
			}
		}
		else if(childs.item(i).getNodeType()==Node.ELEMENT_NODE) {
			foundText=true; 
			break; 
		}
	}
//	Window.alert("elementContainText "+el.getTagName()+": "+foundText); 
	return foundText; 
}


}
